package app.biz.controller;

import app.biz.model.ClientInfo;
import app.biz.model.EcgRequest;
import app.biz.model.EcgResponse;
import app.biz.service.aggregate.EcgResultService;
import app.biz.service.atom.LogService;
import app.framework.controller.base.BaseController;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

@RestController
@RequestMapping("/api")
public class   EcgController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(EcgController.class);

    @Autowired
    EcgResultService resultService;

    @Autowired
    LogService logService;

  /**
   * 接收ECG数据，调用远程AI服务解析程序
   *
   * @param fs
   * @param device_id
   * @param leads
   * @param xmlData
   * @return
   */
  @ApiOperation(
      httpMethod = "POST",
      value = "/api/v1/ecg/parse",
      notes =
          "# ECG XML数据解析 结果内容说明：\n"
              + "<a href=\"/lib/test1.xml.txt\" target='blank'>获取样例数据</a>\n"
              + "95281：心律失常\n"
              + "92497：窦性心动过速\n"
              + "3022： 窦性心动过缓\n"
              + "93713：ST-T改变，心肌缺血\n"
              + "5992:  电轴左偏\n"
              + "56408：肢体导联QRS低电压\n"
              + "21972：胸部导联QRS低电压\n"
              + "99925：电轴正常\n")
  @ApiImplicitParams({
    @ApiImplicitParam(
        name = "fs",
        value = "采样率：前只支持500和1000",
        example = "500",
        allowableValues = "500,1000",
        required = true,
        dataType = "Long"),
    @ApiImplicitParam(
        name = "leads",
        value = "导联数：目前支持12导联",
        required = true,
        allowableValues = "12",
        example = "12",
        dataType = "Long"),
    @ApiImplicitParam(
        name = "device_id",
        value = "设备ID，目前支持\n0:福田,预设500Hz \n1:康泰,预设1000Hz \n2:益体机,预设500Hz",
        example = "0",
        allowableValues = "0,1,2",
        required = true,
        dataType = "Long"),
    @ApiImplicitParam(
        name = "async",
        value = "异步标识：true 时为异步请求，需要稍后通过当前请求返回的SID调用 /api/v1/ecg/query/{sid} 接口查询正确的返回结果",
        example = "false",
        allowableValues = "false,true",
        dataType = "Boolean")
  })
  @PostMapping(
      value = "/v1/ecg/parse/fs/{fs}/leads/{leads}/device_id/{device_id}/async/{async}",
      produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public JSONObject parseEcg(
      @PathVariable int fs,
      @PathVariable int device_id,
      @PathVariable int leads,
      @PathVariable String async,
      @ApiParam(value = "心电xml数据：符合ECG格式的心电XML数据", required = true) @RequestBody String xmlData,
      HttpServletRequest request)  {
      //装填数据
      EcgRequest ecgRequest = EcgRequest.instance()
                .setFs(fs)
                .setDevice_id(device_id)
                .setLeads(leads)
                .setXmlData(xmlData);
      //数据校验（除XML外）
      ecgRequest.validate();
      //生成请求唯一id
      long sid = sequencer.getId();
      logger.info("接收数据：sid={}",sid);
      //设置请求对象的SID
      ecgRequest.setSid(sid);
      //记录客户端信息
      ClientInfo clientInfo = new ClientInfo()
              .setIP(request.getRemoteHost())
              //记录真IP(需要负载均衡器配合支持)
              .setRealIP(request.getHeader("X-real-ip"));

      //记录业务日志
      logService.bizlogAsync(ecgRequest,clientInfo);
      JSONObject result;
      try {
          //异步调用
          if(async!=null && "true".equals(async.toLowerCase())){
              //必须同步保存异步调用的结果，否则没有意义！
              resultService.getRemoteResultAsyncAndSave(ecgRequest,clientInfo);
              return EcgResponse.instance.success(sid);
          }
          //同步调用：
          logger.info("调用算法：sid={}",sid);
          JSONObject resultObj = resultService.getRemoteResult(ecgRequest,clientInfo);
          result = EcgResponse.instance.success(sid, resultObj);
      } catch (Exception e) {
          logger.error("ERROR, sid:{}",sid,e);
          return EcgResponse.instance.failure(e);
      }
      logger.info("返回结果：sid={}",sid);
      return  result;
    }

    @ApiOperation(
            httpMethod = "GET",
            value = "/api/v1/ecg/query/{sid}",
            notes = "# 根据ID查询ECG XML解析结果")
    @GetMapping("/v1/ecg/query/{sid}")
    public JSONObject query(
            @ApiParam(value = "请求提交返回的SID", example ="106443255280963584", required = true)
            @PathVariable long sid) {
      //TODO:数据库超时错误时没有记录？
        JSONObject resultObj =  resultService.findResultBySid(sid);
        return EcgResponse.instance.success(sid, resultObj);
    }

  @ApiOperation(httpMethod = "POST", value = "/api/v1/ecg/feedback/{sid}/", notes = "# 人工诊断结果反馈")
  @PostMapping("/v1/ecg/feedback/{sid}")
  public JSONObject feedback(
      @ApiParam(value = "诊断结果提交时生成的唯一ID", example ="106443255280963584", required = true) @PathVariable long sid,
      @ApiParam(
              value = "诊断结果反馈代码，JSON格式，形如：<br>{\"xk_code\":\"3022,5992\"}",
              required = true)
          @RequestBody
          JSONObject xkFeedBack) {
        logger.info("结果反馈:sid={},feedback={}",sid,xkFeedBack);
        try {
            JSONObject feedback = new JSONObject();
            feedback.put("sid",sid);
            //对本次请求分配唯一id
            long fid = sequencer.getId();
            feedback.put("fid",fid);
//            feedback.put("xk_code",xkFeedBack.get("xk_code"));
            feedback.put("content",xkFeedBack);
            resultService.updateFeedback(feedback);
        } catch (Exception e) {
            logger.error("反馈信息保存失败！sid:{},xkFeedBack:{}",e,sid,xkFeedBack);
            return EcgResponse.instance.failure(e);
        }
        return EcgResponse.instance.success(sid);
    }

}
